<script setup>
import { ref, watch, computed, nextTick } from 'vue'
import { GetFileTree, OpenFile, ShowInExplorer, RefreshFileTree, GetDirectoryChildren } from '../../../wailsjs/go/main/App'
import FileTreeNode from './FileTreeNode.vue'

const props = defineProps({
  currentPath: {
    type: String,
    default: ''
  }
})

const emit = defineEmits(['path-change', 'refresh-complete'])

const fileTree = ref(null)
const loading = ref(false)
const error = ref('')
const expandedFolders = ref(new Set())

const displayData = computed(() => {
  return fileTree.value ? [fileTree.value] : []
})

const loadFileTree = async (path, forceRefresh = false) => {
  if (!path) return
  
  loading.value = true
  error.value = ''
  
  try {
    let tree
    if (forceRefresh) {
      tree = await RefreshFileTree(path)
    } else {
      tree = await GetFileTree(path)
    }
    fileTree.value = tree
    if (forceRefresh) {
      emit('refresh-complete')
    }
  } catch (err) {
    error.value = `加载文件树失败: ${err.message || err}`
    console.error('Failed to load file tree:', err)
  } finally {
    loading.value = false
  }
}

watch(() => props.currentPath, async (newPath) => {
  if (newPath) {
    await loadFileTree(newPath)
  }
}, { immediate: true })

const toggleFolder = async (node) => {
  if (!node.isDir) return
  
  const path = node.path
  if (expandedFolders.value.has(path)) {
    expandedFolders.value.delete(path)
  } else {
    // 如果文件夹还没有加载子目录，则动态加载
    if (!node.children || node.children.length === 0) {
      try {
        const children = await GetDirectoryChildren(path)
        node.children = children || []
      } catch (err) {
        console.error('Failed to load directory children:', err)
        return
      }
    }
    expandedFolders.value.add(path)
  }
}

const handleItemClick = async (node) => {
  if (node.isDir) {
    toggleFolder(node)
  }
  // 单击文件时不再打开，只有双击才打开
}

const handleItemDoubleClick = async (node) => {
  if (node.isDir) {
    // 双击文件夹时直接在资源管理器中打开
    try {
      await ShowInExplorer(node.path)
    } catch (err) {
      console.error('Failed to show folder in explorer:', err)
    }
  } else {
    // 双击文件时打开文件
    try {
      await OpenFile(node.path)
    } catch (err) {
      console.error('Failed to open file:', err)
    }
  }
}

const showInExplorer = async (node) => {
  try {
    await ShowInExplorer(node.path)
  } catch (err) {
    console.error('Failed to show in explorer:', err)
  }
}

const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]
}

const formatDate = (dateString) => {
  const date = new Date(dateString)
  return date.toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  })
}

const refreshFileTree = async () => {
  await loadFileTree(props.currentPath, true)
}

const getFileIcon = (node) => {
  if (node.isDir) {
    return expandedFolders.value.has(node.path) ? 'folder-open' : 'folder'
  }
  
  const ext = node.name.split('.').pop()?.toLowerCase()
  switch (ext) {
    case 'txt':
    case 'md':
    case 'readme':
      return 'file-text'
    case 'js':
    case 'ts':
    case 'vue':
    case 'jsx':
    case 'tsx':
      return 'file-code'
    case 'jpg':
    case 'jpeg':
    case 'png':
    case 'gif':
    case 'svg':
    case 'webp':
      return 'file-image'
    case 'mp4':
    case 'avi':
    case 'mov':
    case 'wmv':
      return 'file-video'
    case 'mp3':
    case 'wav':
    case 'flac':
      return 'file-audio'
    case 'pdf':
      return 'file-pdf'
    case 'zip':
    case 'rar':
    case '7z':
      return 'file-archive'
    default:
      return 'file'
  }
}



// Expose refresh method to parent
defineExpose({
  refreshFileTree
})
</script>

<template>
  <div class="file-tree">
    <div v-if="loading" class="loading">
      <div class="loading-spinner"></div>
      <span>加载中...</span>
    </div>
    
    <div v-else-if="error" class="error">
      <svg class="error-icon" viewBox="0 0 24 24" fill="currentColor">
        <path d="M13,13H11V7H13M13,17H11V15H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" />
      </svg>
      <span>{{ error }}</span>
    </div>
    
    <div v-else class="tree-content">
      <div class="tree-list">
        <template v-for="node in displayData" :key="node.path">
          <FileTreeNode 
            :node="node"
            :expanded-folders="expandedFolders"
            :is-search-mode="false"
            @click="handleItemClick"
            @double-click="handleItemDoubleClick"
            @show-in-explorer="showInExplorer"
            @toggle="toggleFolder"
            :get-file-icon="getFileIcon"
            :format-file-size="formatFileSize"
            :format-date="formatDate"
          />
        </template>
      </div>
    </div>
  </div>
</template>



<style scoped>
.file-tree {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.loading,
.error,
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: 1;
  gap: 12px;
  color: var(--secondary-color);
}

.loading-spinner {
  width: 24px;
  height: 24px;
  border: 2px solid var(--border-color);
  border-top: 2px solid var(--primary-color);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.error-icon,
.empty-icon {
  width: 48px;
  height: 48px;
  opacity: 0.5;
}

.tree-content {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.search-header {
  padding: 8px 16px;
  border-bottom: 1px solid var(--border-color);
  background: var(--header-bg);
}

.search-count {
  font-size: 12px;
  color: var(--secondary-color);
  font-weight: 500;
}

.tree-list {
  flex: 1;
  overflow-y: auto;
}

.tree-node {
  user-select: none;
}

.node-content {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  cursor: pointer;
  transition: background-color 0.2s ease;
  border-radius: 4px;
  margin: 1px 4px;
}

.node-content:hover {
  background: var(--hover-bg);
}

.node-content.is-directory {
  font-weight: 500;
}

.node-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.icon {
  width: 16px;
  height: 16px;
  color: var(--icon-color);
}

.node-info {
  flex: 1;
  min-width: 0;
}

.node-name {
  font-size: 14px;
  line-height: 1.4;
  word-break: break-all;
}

.node-details {
  display: flex;
  gap: 12px;
  font-size: 11px;
  color: var(--secondary-color);
  margin-top: 2px;
}

.node-path {
  font-size: 11px;
  color: var(--secondary-color);
  margin-top: 2px;
  word-break: break-all;
}

.file-size,
.file-date {
  white-space: nowrap;
}

/* Light theme */
.light-theme .file-tree {
  --primary-color: #3b82f6;
  --secondary-color: #6b7280;
  --border-color: #e5e7eb;
  --header-bg: #f9fafb;
  --hover-bg: #f3f4f6;
  --icon-color: #6b7280;
}

/* Dark theme */
.dark-theme .file-tree {
  --primary-color: #60a5fa;
  --secondary-color: #9ca3af;
  --border-color: #374151;
  --header-bg: #1f2937;
  --hover-bg: #374151;
  --icon-color: #9ca3af;
}
</style>